package com.zdp.leetcode;

/*
* 题目描述
* 小朋友 A 在和 ta 的小伙伴们玩传信息游戏，游戏规则如下：
有 n 名玩家，所有玩家编号分别为 0 ～ n-1，其中小朋友 A 的编号为 0
每个玩家都有固定的若干个可传信息的其他玩家（也可能没有）。传信息的关系是单向的（比如 A 可以向 B 传信息，但 B 不能向 A 传信息）。
每轮信息必须需要传递给另一个人，且信息可重复经过同一个人
给定总玩家数 n，以及按 [玩家编号,对应可传递玩家编号] 关系组成的二维数组 relation。返回信息从小 A (编号 0 ) 经过 k 轮传递到编号为 n-1 的小伙伴处的方案数；若不能到达，返回 0。
示例 1：
输入：n = 5, relation = [[0,2],[2,1],[3,4],[2,3],[1,4],[2,0],[0,4]], k = 3
输出：3
解释：信息从小 A 编号 0 处开始，经 3 轮传递，到达编号 4。共有 3 种方案，分别是 0->2->0->4， 0->2->1->4， 0->2->3->4。
示例 2：
输入：n = 3, relation = [[0,2],[2,1]], k = 2
输出：0
解释：信息不能从小 A 处经过 2 轮传递到编号 2
限制：
2 <= n <= 10
1 <= k <= 5
1 <= relation.length <= 90, 且 relation[i].length == 2
0 <= relation[i][0],relation[i][1] < n 且 relation[i][0] != relation[i][1]

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/chuan-di-xin-xi
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
* */
public class 传递信息 {
    public static void main(String[] args) {
        传递信息 demo = new 传递信息();
        int[][] relation = new int[][]{{0,2},{2,1},{3,4},{2,3},{1,4},{2,0},{0,4}};
        demo.numWays(5,relation,3);
        System.out.println(demo.result);
    }
    //使用深度优先搜索
    //因为可以重复通过，所以不进行走过的标记
    //因为限定了传递的次数，所以对于传递次数大于限定的次数时，可以直接返回
    int result = 0;
    public int numWays(int n, int[][] relation, int k) {
        int[][] map = new int[n][n];
        for(int i=0;i<relation.length;i++){ //构造一张图
            map[relation[i][0]][relation[i][1]]=1; //初始化一下关系
        }
        search(0,map,k,0);
        return result;
    }
    public void search(int i,int[][]map,int k,int count){
       if(count>k){ //超过了限定的传递次数
           return ;
       }
        if(i==map.length-1&&count==k){
            this.result +=1; //找到n-1编号的人，方案数+1
            return ;
        }
        for(int j=0;j<map[i].length;j++){
            if(map[i][j]!=0) //如果有路，就进行搜索，传递次数+1
               search(j,map,k,count+1);
        }
    }
    //使用到递归，就可以用动态规划来进行优化
    /*
    * numWasy(n,k) ===> 计算经过k轮，可以传递给n-1的方案数
    * 传递到 n-1 ===> 假设 x1,x2,x3...可以传递到n-1 ===> 则n-1的方案数 = numWasy(x1,k-1)+numWasy(x2,k-1)+numWasy(x3,k-1)
    * 因为传入的relation 数组是 [x,y] ===> 所以 dp[i+1][y] += dp[i][x]
    * */
    public int numWays1(int n, int[][] relation, int k) {
        int[][] dp = new int[k+1][n];
        dp[0][0] = 1; //不被依赖
        //dp 中的其他初始值都为0 ，因为是从0开始传递的
        for(int i=0;i<k;i++){
            for(int j=0;j<relation.length;j++){
                int y = relation[j][1];
                int x = relation[j][0];
                dp[i+1][y] += dp[i][x];
            }
        }
        return dp[k][n-1];
    }
}

